﻿#region zh-CHS 2006 - 2007 DemoSoft 团队 | en 2006 - 2007 DemoSoft Team

//     NOTES
// ---------------
//
// This file is a part of the G.O.S.E(Game Online Server Engine) for .NET.
//
//                 2006-2007 DemoSoft Team
//
//
// First Version : by H.Q.Cai - mailto:caihuanqing@hotmail.com

/***************************************************************************
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published
 *   by the Free Software Foundation; either version 2.1 of the License, or
 *   (at your option) any later version.
 *
 ***************************************************************************/

#region zh-CHS 包含名字空间 | en Include namespace
using System;
using System.Threading;
using System.Diagnostics;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Demo_G.O.S.E.ServerEngine.Common;
#endregion

namespace Demo_G.O.S.E.ServerEngine.Network.DLL
{
    /// <summary>
    /// 主网络监听服务
    /// </summary>
    [MultiThreadedSupportgAttribute( "当前的类所有成员都可锁定,支持多线程操作" )]
    public class ACESocketMainServer
    {
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 主网络监听服务的指针
        /// </summary>
        private IntPtr m_SocketMainServer                                                                       = IntPtr.Zero;
        /// <summary>
        /// 主网络监听服务的管理(所有客户端的)服务
        /// </summary>
        private ACESocketHandlerManagerAtServer m_SocketHandlerManagerAtServer                                  = new ACESocketHandlerManagerAtServer();
        /// <summary>
        /// 处理数据时的回调函数
        /// </summary>
        private DelegateProcessMessageBlock m_ProcessMessageBlock                                               = null;
        /// <summary>
        /// 处理断开时的回调函数
        /// </summary>
        private DelegateDisconnect m_Disconnect                                                                 = null;
        /// <summary>
        /// 处理连接时的回调函数
        /// </summary>
        private DelegateAcceptor m_Acceptor                                                                     = null;
        #endregion

        #region zh-CHS 构造和初始化和清理 | en Constructors and Initializers and Dispose
        /// <summary>
        /// 初始化构造
        /// </summary>
        public ACESocketMainServer()
        {
            m_ProcessMessageBlock   = new DelegateProcessMessageBlock(this.OnProcessMessageBlock);
            m_Disconnect            = new DelegateDisconnect(this.OnDisconnect);
            m_Acceptor              = new DelegateAcceptor(this.OnAcceptor);
        }
        #endregion

        #region zh-CHS 共有属性 | en Public Properties
        /// <summary>
        /// 是否已经连接
        /// </summary>
        public bool IsConnected
        {
            get { return ACESocketMainServer.ACESocketMainServer_IsConnected(m_SocketMainServer); }
        }

        /// <summary>
        /// 主网络监听服务的管理(所有客户端的)服务
        /// </summary>
        public ACESocketHandlerManagerAtServer SocketHandlerManager
        {
            get { return m_SocketHandlerManagerAtServer; }
        }
        #endregion

        #region zh-CHS 共有方法 | en Public Methods
        /// <summary>
        /// 开始监听服务
        /// </summary>
        /// <param name="iPort">监听的端口</param>
        public bool StartServer(int iPort)
        {
            if (ACESocketMainServer.ACESocketMainServer_StartServer(iPort, m_ProcessMessageBlock, m_Disconnect, m_Acceptor, ref m_SocketMainServer) == false)
            {
                Debug.WriteLine("ACESocketMainServer.StartServer(...) - ACESocketMainServer.ACESocketMainServer_StartServer(...) == false error!");
                return false;
            }

            IntPtr l_SocketHandlerManagerAtServer   = IntPtr.Zero;
            if (ACESocketMainServer.ACESocketMainServer_GetSocketHandlerManager(ref l_SocketHandlerManagerAtServer, m_SocketMainServer) == false)
            {
                Debug.WriteLine("ACESocketMainServer.StartServer(...) - ACESocketMainServer.ACESocketMainServer_GetSocketHandlerManager(...) == false error!");
                return false;
            }

            if (l_SocketHandlerManagerAtServer == IntPtr.Zero)
            {
                Debug.WriteLine("ACESocketMainServer.StartServer(...) - l_SocketHandlerManagerAtServer == IntPtr.Zero error!");
                return false;
            }

            m_SocketHandlerManagerAtServer.Value = l_SocketHandlerManagerAtServer;
            return true;
        }

        /// <summary>
        /// 开始监听指定的地址服务
        /// </summary>
        /// <param name="strHostNamePort">地址和端口</param>
        public bool StartServer(string strHostNamePort)
        {
            if (ACESocketMainServer.ACESocketMainServer_StartServer2(strHostNamePort, m_ProcessMessageBlock, m_Disconnect, m_Acceptor, ref m_SocketMainServer) == false)
            {
                Debug.WriteLine("ACESocketMainServer.StartServer(...) - ACESocketMainServer.ACESocketMainServer_StartServer(...) == false error!");
                return false;
            }

            IntPtr l_SocketHandlerManagerAtServer = IntPtr.Zero;
            if (ACESocketMainServer.ACESocketMainServer_GetSocketHandlerManager(ref l_SocketHandlerManagerAtServer, m_SocketMainServer) == false)
            {
                Debug.WriteLine("ACESocketMainServer.StartServer(...) - ACESocketMainServer.ACESocketMainServer_GetSocketHandlerManager(...) == false error!");
                return false;
            }

            if (l_SocketHandlerManagerAtServer == IntPtr.Zero)
            {
                Debug.WriteLine("ACESocketMainServer.StartServer(...) - l_SocketHandlerManagerAtServer == IntPtr.Zero error!");
                return false;
            }

            m_SocketHandlerManagerAtServer.Value = l_SocketHandlerManagerAtServer;
            return true;
        }

        /// <summary>
        /// 停止服务
        /// </summary>
        public void StopServer()
        {
            ACESocketMainServer.ACESocketMainServer_StopServer(m_SocketMainServer);
        }
        #endregion

        #region zh-CHS 共有事件 | en Public Event
        /// <summary>
        ///  处理数据时的事件
        /// </summary>
        public event EventDelegateProcessMessageBlock EventThreadProcessMessageBlock;
        /// <summary>
        /// 处理断开时的事件
        /// </summary>
        public event EventDelegateDisconnect EventThreadDisconnect;
        /// <summary>
        /// 处理连接时的事件
        /// </summary>
        public event EventDelegateAcceptor EventThreadAcceptor;
        #endregion

        #region zh-CHS 私有委托 | en Private Delegate
        /// <summary>
        /// 处理数据时的委托
        /// </summary>
        /// <param name="pRecvMessageBlock"></param>
        /// <param name="pNonceClientHandler"></param>
        /// <param name="pAllHandlerManager"></param>
        private delegate void DelegateProcessMessageBlock(IntPtr pRecvMessageBlock, IntPtr pNonceClientHandler, IntPtr pAllHandlerManager);
        /// <summary>
        /// 处理断开时的委托
        /// </summary>
        /// <param name="pNonceClientHandler"></param>
        /// <param name="pAllHandlerManager"></param>
        private delegate void DelegateDisconnect(IntPtr pNonceClientHandler, IntPtr pAllHandlerManager);
        /// <summary>
        /// 处理连接时的委托
        /// </summary>
        /// <param name="pNonceClientHandler"></param>
        /// <param name="pAllHandlerManager"></param>
        /// <param name="DelegateProcessMessageBlock"></param>
        /// <param name="DelegateDisconnect"></param>
        private delegate void DelegateAcceptor(IntPtr pNonceClientHandler, IntPtr pAllHandlerManager, out ACEClientHandlerAtServer.DelegateClientHandlerProcessMessageBlock DelegateProcessMessageBlock, out ACEClientHandlerAtServer.DelegateClientHandlerDisconnect DelegateDisconnect);
        #endregion

        #region zh-CHS 私有的事件处理函数 | en Private Event Handlers

        #region zh-CHS 私有成员变量 | en Private Member Variables
        // 为优化而采用内存池
        /// <summary>
        /// 数据包
        /// </summary>
        private ACEProcessMessageBlockPool<ACEMessageBlock> m_MessageBlockPool = new ACEProcessMessageBlockPool<ACEMessageBlock>("ACESocketMainServer - ACEMessageBlock", 1024);
        /// <summary>
        /// 客户端
        /// </summary>
        private ACEProcessMessageBlockPool<ACEClientHandlerAtServer> m_ClientHandlerAtServerPool = new ACEProcessMessageBlockPool<ACEClientHandlerAtServer>( "ACESocketMainServer - ACEClientHandlerAtServer", 1024 );
        /// <summary>
        /// 服务端主管理
        /// </summary>
        private ACEProcessMessageBlockPool<ACESocketHandlerManagerAtServer> m_SocketHandlerManagerAtServerPool = new ACEProcessMessageBlockPool<ACESocketHandlerManagerAtServer>( "ACESocketMainServer - ACESocketHandlerManagerAtServer", 1024 );
        #endregion
        /// <summary>
        /// 处理数据
        /// </summary>
        /// <param name="pRecvMessageBlock"></param>
        /// <param name="pNonceClientHandler"></param>
        /// <param name="pAllHandlerManager"></param>
        private void OnProcessMessageBlock(IntPtr pRecvMessageBlock, IntPtr pNonceClientHandler, IntPtr pAllHandlerManager)
        {
            if (EventThreadProcessMessageBlock != null)
            {
                // 从内存池获取内存 - 调用太频繁内存池优化
                ACEMessageBlock l_RecvMessageBlock = m_MessageBlockPool.AcquirePoolContent();
                if (l_RecvMessageBlock == null)
                {
                    Debug.WriteLine("ACESocketMainServer.OnProcessMessageBlock(...) - l_RecvMessageBlock == null error!");
                    
                    return;
                }
                l_RecvMessageBlock.Value = pRecvMessageBlock;

                ACEClientHandlerAtServer l_NonceClientHandler = m_ClientHandlerAtServerPool.AcquirePoolContent();
                if (l_NonceClientHandler == null)
                {
                    Debug.WriteLine("ACESocketMainServer.OnProcessMessageBlock(...) - l_NonceClientHandler == null error!");
                    
                    m_MessageBlockPool.ReleasePoolContent(l_RecvMessageBlock);

                    return;
                }
                l_NonceClientHandler.Value = pNonceClientHandler;

                ACESocketHandlerManagerAtServer l_AllHandlerManager = m_SocketHandlerManagerAtServerPool.AcquirePoolContent();
                if (l_AllHandlerManager == null)
                {
                    Debug.WriteLine("ACESocketMainServer.OnProcessMessageBlock(...) - l_AllHandlerManager == null error!");
                    
                    m_MessageBlockPool.ReleasePoolContent(l_RecvMessageBlock);
                    m_ClientHandlerAtServerPool.ReleasePoolContent(l_NonceClientHandler);
                    return;
                }
                l_AllHandlerManager.Value = pAllHandlerManager;

                EventThreadProcessMessageBlock(l_RecvMessageBlock, l_NonceClientHandler, l_AllHandlerManager);

                // 释放入内存池
                m_MessageBlockPool.ReleasePoolContent(l_RecvMessageBlock);
                m_ClientHandlerAtServerPool.ReleasePoolContent(l_NonceClientHandler);
                m_SocketHandlerManagerAtServerPool.ReleasePoolContent(l_AllHandlerManager);
            }
        }

        /// <summary>
        /// 处理断开
        /// </summary>
        /// <param name="pNonceClientHandler"></param>
        /// <param name="pAllHandlerManager"></param>
        private void OnDisconnect(IntPtr pNonceClientHandler, IntPtr pAllHandlerManager)
        {
            if (EventThreadDisconnect != null)
            {
                // 从内存池获取内存 - 调用太频繁内存池优化
                ACEClientHandlerAtServer l_NonceClientHandler = m_ClientHandlerAtServerPool.AcquirePoolContent();
                if (l_NonceClientHandler == null)
                {
                    Debug.WriteLine("ACESocketMainServer.OnProcessMessageBlock(...) - l_NonceClientHandler == null error!");
                    
                    return;
                }
                l_NonceClientHandler.Value = pNonceClientHandler;

                ACESocketHandlerManagerAtServer l_AllHandlerManager = m_SocketHandlerManagerAtServerPool.AcquirePoolContent();
                if (l_AllHandlerManager == null)
                {
                    Debug.WriteLine("ACESocketMainServer.OnProcessMessageBlock(...) - l_AllHandlerManager == null error!");
                    
                    m_ClientHandlerAtServerPool.ReleasePoolContent(l_NonceClientHandler);

                    return;
                }
                l_AllHandlerManager.Value = pAllHandlerManager;

                EventThreadDisconnect(l_NonceClientHandler, l_AllHandlerManager);

                // 释放入内存池
                m_ClientHandlerAtServerPool.ReleasePoolContent(l_NonceClientHandler);
                m_SocketHandlerManagerAtServerPool.ReleasePoolContent(l_AllHandlerManager);
            }
        }

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 用来保存ACEClientHandlerAtServer数据,阻止垃圾回收的调用
        /// </summary>
        private List<ACEClientHandlerAtServer> m_ClientHandlerAtServer  = new List<ACEClientHandlerAtServer>();
        /// <summary>
        /// 
        /// </summary>
        private object m_LockClientHandlerAtServer                      = new object();
        #endregion
        /// <summary>
        /// 处理连接
        /// </summary>
        /// <param name="pNonceClientHandler"></param>
        /// <param name="pAllHandlerManager"></param>
        /// <param name="DelegateProcessMessageBlock"></param>
        /// <param name="DelegateDisconnect"></param>
        private void OnAcceptor(IntPtr pNonceClientHandler, IntPtr pAllHandlerManager, out ACEClientHandlerAtServer.DelegateClientHandlerProcessMessageBlock DelegateProcessMessageBlock, out ACEClientHandlerAtServer.DelegateClientHandlerDisconnect DelegateDisconnect)
        {
            DelegateProcessMessageBlock = null;
            DelegateDisconnect          = null;

            if (EventThreadAcceptor != null)
            {
                // 从内存池获取内存 - 调用太频繁内存池优化
                ACEClientHandlerAtServer l_NonceClientHandler = m_ClientHandlerAtServerPool.AcquirePoolContent();
                if (l_NonceClientHandler == null)
                {
                    Debug.WriteLine("ACESocketMainServer.OnProcessMessageBlock(...) - l_NonceClientHandler == null error!");

                    return;
                }
                l_NonceClientHandler.Value  = pNonceClientHandler;

                ACESocketHandlerManagerAtServer l_AllHandlerManager = m_SocketHandlerManagerAtServerPool.AcquirePoolContent();
                if (l_AllHandlerManager == null)
                {
                    Debug.WriteLine("ACESocketMainServer.OnProcessMessageBlock(...) - l_AllHandlerManager == null error!");
                    
                    m_ClientHandlerAtServerPool.ReleasePoolContent(l_NonceClientHandler);

                    return;
                }
                l_AllHandlerManager.Value   = pAllHandlerManager;

                ACEClientHandlerAtServer l_ClientHandlerAtServer = null;
                EventThreadAcceptor(l_NonceClientHandler, l_AllHandlerManager, out l_ClientHandlerAtServer);

                if (l_ClientHandlerAtServer != null)
                {
                    l_ClientHandlerAtServer.Value = pNonceClientHandler;
                    DelegateProcessMessageBlock = l_ClientHandlerAtServer.m_ProcessMessageBlock;
                    DelegateDisconnect = l_ClientHandlerAtServer.m_Disconnect;

                    Monitor.Enter(m_LockClientHandlerAtServer);
                    {
                        // 保存ACEClientHandlerAtServer数据,阻止垃圾回收的调用,防止回调函数失败
                        m_ClientHandlerAtServer.Add(l_ClientHandlerAtServer);
                    }
                    Monitor.Exit(m_LockClientHandlerAtServer);
                }

                // 释放入内存池
                m_ClientHandlerAtServerPool.ReleasePoolContent(l_NonceClientHandler);
                m_SocketHandlerManagerAtServerPool.ReleasePoolContent(l_AllHandlerManager);
            }
        }

        #endregion

        #region zh-CHS 引入DLL接口 | en DLL Import
        /// <summary>
        /// dll 调用
        /// </summary>
        /// <param name="iPort"></param>
        /// <param name="DelegateProcessMessageBlock"></param>
        /// <param name="DelegateDisconnect"></param>
        /// <param name="DelegateAcceptor"></param>
        /// <param name="pSocketMainServer"></param>
        /// <returns></returns>
        [DllImport("Demo G.O.S.E.Net.dll", CallingConvention = CallingConvention.StdCall)]
        private static extern bool ACESocketMainServer_StartServer(int iPort, DelegateProcessMessageBlock DelegateProcessMessageBlock, DelegateDisconnect DelegateDisconnect, DelegateAcceptor DelegateAcceptor, ref IntPtr pSocketMainServer);

        /// <summary>
        /// dll 调用
        /// </summary>
        /// <param name="strHostNamePort"></param>
        /// <param name="DelegateProcessMessageBlock"></param>
        /// <param name="DelegateDisconnect"></param>
        /// <param name="DelegateAcceptor"></param>
        /// <param name="pSocketMainServer"></param>
        /// <returns></returns>
        [DllImport("Demo G.O.S.E.Net.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
        private static extern bool ACESocketMainServer_StartServer2(string strHostNamePort, DelegateProcessMessageBlock DelegateProcessMessageBlock, DelegateDisconnect DelegateDisconnect, DelegateAcceptor DelegateAcceptor, ref IntPtr pSocketMainServer);

        /// <summary>
        /// dll 调用
        /// </summary>
        /// <param name="pSocketMainServer"></param>
        [DllImport("Demo G.O.S.E.Net.dll", CallingConvention = CallingConvention.StdCall)]
        private static extern void ACESocketMainServer_StopServer(IntPtr pSocketMainServer);

        /// <summary>
        /// dll 调用
        /// </summary>
        /// <param name="pSocketMainServer"></param>
        /// <returns></returns>
        [DllImport("Demo G.O.S.E.Net.dll", CallingConvention = CallingConvention.StdCall)]
        private static extern bool ACESocketMainServer_IsConnected(IntPtr pSocketMainServer);

        /// <summary>
        /// dll 调用
        /// </summary>
        /// <param name="pSocketHandlerManagerAtServer"></param>
        /// <param name="pSocketMainServer"></param>
        /// <returns></returns>
        [DllImport("Demo G.O.S.E.Net.dll", CallingConvention = CallingConvention.StdCall)]
        private static extern bool ACESocketMainServer_GetSocketHandlerManager(ref IntPtr pSocketHandlerManagerAtServer, IntPtr pSocketMainServer);
        #endregion
    }
}
#endregion

